﻿using System;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;

namespace SXICE.Core.Helpers
{
    /// <summary>
    /// 通用帮助类
    /// </summary>
    public class CommonHelper
    {
        /// <summary>
        /// 从身份证号中提取生日
        /// </summary>
        /// <param name="idNumber">身份证号</param>
        /// <returns>结果</returns>
        public static DateTime? ExtracBorthFromIDNumber(string idNumber)
        {
            if (idNumber.IsNullOrEmpty() || !Regex.IsMatch(idNumber, @"(^\d{15}$)|(^\d{17}[\dXx]$)"))
                return null;
            if (idNumber.Length == 15)
            {
                if (DateTime.TryParseExact($"19{idNumber.Substring(6, 6)}", "yyyyMMdd", Thread.CurrentThread.CurrentUICulture, System.Globalization.DateTimeStyles.None, out var birth))
                    return birth;
                return null;
            }
            if (DateTime.TryParseExact(idNumber.Substring(6, 8), "yyyyMMdd", Thread.CurrentThread.CurrentUICulture, System.Globalization.DateTimeStyles.None, out var birthday))
                return birthday;
            return null;
        }

        /// <summary>
        /// 从身份证号获取年龄
        /// </summary>
        /// <param name="idNumber">身份证号</param>
        /// <returns>结果</returns>
        public static int? GetAgeFromIDNumber(string idNumber)
        {
            var birthday = ExtracBorthFromIDNumber(idNumber);
            if (!birthday.HasValue)
                return null;
            return GetAge(birthday.Value);
        }

        /// <summary>
        /// 从身份证中判断是否为男性
        /// </summary>
        /// <param name="idNumber">身份证号</param>
        /// <returns>结果</returns>
        public static bool? IsManFromIDNumber(string idNumber)
        {
            if (idNumber.IsNullOrEmpty() || !Regex.IsMatch(idNumber, @"(^\d{15}$)|(^\d{17}[\dXx]$)"))
                return null;
            if (idNumber.Length == 15)
                return int.Parse(idNumber[14].ToString()) % 2 == 1;
            return int.Parse(idNumber[16].ToString()) % 2 == 1;
        }

        /// <summary>
        /// 获取年龄
        /// </summary>
        /// <param name="birthday">生日</param>
        /// <returns>结果</returns>
        public static int GetAge(DateTime birthday)
        {
            var today = DateTime.Today;
            int age = today.Year - birthday.Year;
            //二月要特殊处理
            if (today.Month == 2 && birthday.Month == 2)
            {
                //如果生日是二月的最后一天，则对比今天是否是二月的最后一天，如果不是则年龄-1
                if (birthday.AddDays(1).Month == 3 && today.AddDays(1).Month == 2)
                    age--;
                return age;
            }
            if (today.Month < birthday.Month || (today.Month == birthday.Month && today.Day < birthday.Day))
                age--;
            return age;
        }

        /// <summary>
        /// 获取性别
        /// </summary>
        /// <param name="idNumber">身份证号</param>
        /// <returns>性别</returns>
        public static string GetSex(string idNumber)
        {
            return int.Parse(idNumber.Substring(16, 1)) % 2 == 0 ? "女" : "男";
        }

        /// <summary>
        /// 时间是否交叉
        /// </summary>
        /// <param name="start">起始时间</param>
        /// <param name="end">结束时间</param>
        /// <param name="start1">起始时间</param>
        /// <param name="end1">结束时间</param>
        /// <returns></returns>
        public static bool IntersectTime(DateTime start, DateTime end, DateTime start1, DateTime end1)
        {
            return (start >= start1 && start <= end1) || (end >= start1 && end <= end1) || (start1 >= start && start1 <= end) || (end1 >= start && end1 <= end);
        }

        /// <summary>
        /// 时间是否包含
        /// </summary>
        /// <param name="start">起始时间</param>
        /// <param name="end">结束时间</param>
        /// <param name="start1">起始时间</param>
        /// <param name="end1">结束时间</param>
        /// <returns></returns>
        public static bool ContainTime(DateTime start, DateTime end, DateTime start1, DateTime end1)
        {
            return start1 >= start && end1 <= end;
        }

        /// <summary>
        /// 将数字四舍五入
        /// </summary>
        /// <param name="value">要计算的值</param>
        /// <returns>结果</returns>
        public static int Round(double value)
        {
            var number = (int)Math.Round(value);
            if (number < 10)
                return number;
            var lastNumber = int.Parse(number.ToString()[number.ToString().Length - 1] + "");
            number -= lastNumber;
            if (lastNumber > 4)
                number += 10;
            return number;
        }

        /// <summary>
        /// Get获取
        /// </summary>
        /// <param name="url">请求url</param>
        /// <param name="timeOut">超时时间</param>
        /// <returns>结果</returns>
        public static string HttpGet(string url, int timeOut = 0)
        {
            var client = new WebClientT();
            return client.DownloadString(url, timeOut);
        }

        /// <summary>
        /// Post提交
        /// </summary>
        /// <param name="url">请求url</param>
        /// <param name="parameters">参数</param>
        /// <param name="timeOut">超时时间</param>
        /// <param name="contentType">ContentType，默认json</param>
        /// <returns>结果</returns>
        public static string HttpPost(string url, string parameters, int timeOut = 0, string contentType = "application/json")
        {
            var client = new WebClientT();
            client.Headers.Add(HttpRequestHeader.ContentType, contentType);
            return Encoding.UTF8.GetString(client.UploadData(url, Encoding.UTF8.GetBytes(parameters), timeOut));
        }
    }

    /// <summary>
    /// 能支持TimeOut的WebClient
    /// </summary>
    public class WebClientT : WebClient
    {
        /// <summary>
        /// 超时时间
        /// </summary>
        private int timeOut = 0;

        /// <summary>
        /// 获取WebRequest
        /// </summary>
        /// <param name="address">地址</param>
        /// <returns>结果</returns>
        protected override WebRequest GetWebRequest(Uri address)
        {
            var webRequest = base.GetWebRequest(address);
            if (timeOut > 0)
                webRequest.Timeout = timeOut;
            return webRequest;
        }

        /// <summary>
        /// 下载字符串
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="timeOut">超时时间</param>
        /// <returns>结果</returns>
        public string DownloadString(string url, int timeOut = 0)
        {
            this.timeOut = timeOut;
            return base.DownloadString(url);
        }

        /// <summary>
        /// 下载数据
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="data">传递的数据</param>
        /// <param name="timeOut">超时时间</param>
        /// <returns>结果</returns>
        public byte[] UploadData(string url, byte[] data, int timeOut = 0)
        {
            this.timeOut = timeOut;
            return base.UploadData(url, data);
        }
    }
}
